#pragma once

#include <Arduino.h>
#include <vector>

/**
 * @brief AX.25 UI 帧结构体，用于在无线电与业务层之间传递信息
 *
 * 为保证中文说明的可读性，字段命名尽量贴近 APRS 语义：
 * - destination/source  表示目的/源呼号（含 SSID）
 * - digipeaters         转发路径（若无可为空）
 * - info                信息字段原始字节序列（通常为 APRS 文本）
 * - control/pid         控制与 PID 字段，常见 UI 帧固定为 0x03 / 0xF0
 * - fcsOk               FCS 校验是否通过
 */
struct Ax25Frame {
  String destination;
  String source;
  std::vector<String> digipeaters;
  std::vector<uint8_t> info;
  uint8_t control = 0x03;
  uint8_t pid = 0xF0;
  bool fcsOk = false;
};

/**
 * @brief  将 UI 帧元素编码为 AX.25 原始字节序列（未包含 FLAG 与 NRZI）
 *
 * @param dest  目的呼号（形如 "APRS" 或 "CQ"）
 * @param src   源呼号（形如 "BD3ND-10"）
 * @param digis 转发路径列表（可为空）
 * @param info  信息字段内容
 * @param out   输出的原始帧字节序列（含 Control/PID 与 FCS）
 * @return true 编码成功
 */
bool ax25_buildUIFrame(const String &dest,
                       const String &src,
                       const std::vector<String> &digis,
                       const std::vector<uint8_t> &info,
                       std::vector<uint8_t> &out);

/**
 * @brief 解析 AX.25 原始帧（不含 FCS，已通过校验）为结构体
 *
 * @param frame 原始字节序列（地址字段 + Control + PID + Info）
 * @param out   解析结果
 * @return true 解析成功
 */
bool ax25_parseFrame(const std::vector<uint8_t> &frame, Ax25Frame &out);

/**
 * @brief 计算 AX.25 FCS（CRC-16-IBM，多项式 0x8408）
 */
uint16_t ax25_calcFcs(const uint8_t *data, size_t len);

/**
 * @brief 校验帧内容与接收到的 FCS 是否匹配
 */
bool ax25_verifyFcs(const std::vector<uint8_t> &frame, uint16_t recvFcs);

